home *** CD-ROM | disk | FTP | other *** search
/ Programming Windows (5th Edition) / Programming Windows, 5th ed. - Companion CD (097-0002183)(1999).iso / Chap06 / KeyView2 / KeyView2.c next >
Encoding:
C/C++ Source or Header  |  1998-10-09  |  7.6 KB  |  215 lines

  1. /*--------------------------------------------------------
  2.    KEYVIEW2.C -- Displays Keyboard and Character Messages
  3.                  (c) Charles Petzold, 1998
  4.   --------------------------------------------------------*/
  5.  
  6. #include <windows.h>
  7.  
  8. LRESULT CALLBACK WndProc (HWND, UINT, WPARAM, LPARAM) ;
  9.  
  10. int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance,
  11.                     PSTR szCmdLine, int iCmdShow)
  12. {
  13.      static TCHAR szAppName[] = TEXT ("KeyView2") ;
  14.      HWND         hwnd ;
  15.      MSG          msg ;
  16.      WNDCLASS     wndclass ;
  17.      
  18.      wndclass.style         = CS_HREDRAW | CS_VREDRAW ;
  19.      wndclass.lpfnWndProc   = WndProc ;
  20.      wndclass.cbClsExtra    = 0 ;
  21.      wndclass.cbWndExtra    = 0 ;
  22.      wndclass.hInstance     = hInstance ;
  23.      wndclass.hIcon         = LoadIcon (NULL, IDI_APPLICATION) ;
  24.      wndclass.hCursor       = LoadCursor (NULL, IDC_ARROW) ;
  25.      wndclass.hbrBackground = (HBRUSH) GetStockObject (WHITE_BRUSH) ;
  26.      wndclass.lpszMenuName  = NULL ;
  27.      wndclass.lpszClassName = szAppName ;
  28.  
  29.      if (!RegisterClass (&wndclass))
  30.      {
  31.           MessageBox (NULL, TEXT ("This program requires Windows NT!"), 
  32.                       szAppName, MB_ICONERROR) ;
  33.           return 0 ;
  34.      }
  35.      
  36.      hwnd = CreateWindow (szAppName, TEXT ("Keyboard Message Viewer #2"),
  37.                           WS_OVERLAPPEDWINDOW,
  38.                           CW_USEDEFAULT, CW_USEDEFAULT,
  39.                           CW_USEDEFAULT, CW_USEDEFAULT,
  40.                           NULL, NULL, hInstance, NULL) ;
  41.      
  42.      ShowWindow (hwnd, iCmdShow) ;
  43.      UpdateWindow (hwnd) ;
  44.      
  45.      while (GetMessage (&msg, NULL, 0, 0))
  46.      {
  47.           TranslateMessage (&msg) ;
  48.           DispatchMessage (&msg) ;
  49.      }
  50.      return msg.wParam ;
  51. }
  52.  
  53. LRESULT CALLBACK WndProc (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
  54. {
  55.      static DWORD dwCharSet = DEFAULT_CHARSET ;            
  56.      static int   cxClientMax, cyClientMax, cxClient, cyClient, cxChar, cyChar ;
  57.      static int   cLinesMax, cLines ;
  58.      static PMSG  pmsg ;
  59.      static RECT  rectScroll ;
  60.      static TCHAR szTop[] = TEXT ("Message        Key       Char     ")
  61.                             TEXT ("Repeat Scan Ext ALT Prev Tran") ;
  62.      static TCHAR szUnd[] = TEXT ("_______        ___       ____     ")
  63.                             TEXT ("______ ____ ___ ___ ____ ____") ;
  64.  
  65.      static TCHAR * szFormat[2] = { 
  66.           
  67.                TEXT ("%-13s %3d %-15s%c%6u %4d %3s %3s %4s %4s"),
  68.                TEXT ("%-13s            0x%04X%1s%c %6u %4d %3s %3s %4s %4s") } ;
  69.  
  70.      static TCHAR * szYes  = TEXT ("Yes") ;
  71.      static TCHAR * szNo   = TEXT ("No") ;
  72.      static TCHAR * szDown = TEXT ("Down") ;
  73.      static TCHAR * szUp   = TEXT ("Up") ;
  74.  
  75.      static TCHAR * szMessage [] = { 
  76.                          TEXT ("WM_KEYDOWN"),    TEXT ("WM_KEYUP"), 
  77.                          TEXT ("WM_CHAR"),       TEXT ("WM_DEADCHAR"), 
  78.                          TEXT ("WM_SYSKEYDOWN"), TEXT ("WM_SYSKEYUP"), 
  79.                          TEXT ("WM_SYSCHAR"),    TEXT ("WM_SYSDEADCHAR") } ;
  80.      HDC          hdc ;
  81.      int          i, iType ;
  82.      PAINTSTRUCT  ps ;
  83.      TCHAR        szBuffer[128], szKeyName [32] ;
  84.      TEXTMETRIC   tm ;
  85.  
  86.      switch (message)
  87.      {
  88.      case WM_INPUTLANGCHANGE:
  89.           dwCharSet = wParam ;
  90.                                    // fall through
  91.      case WM_CREATE:
  92.      case WM_DISPLAYCHANGE:
  93.      
  94.                // Get maximum size of client area
  95.  
  96.           cxClientMax = GetSystemMetrics (SM_CXMAXIMIZED) ;
  97.           cyClientMax = GetSystemMetrics (SM_CYMAXIMIZED) ;
  98.  
  99.               // Get character size for fixed-pitch font
  100.  
  101.           hdc = GetDC (hwnd) ;
  102.  
  103.           SelectObject (hdc, CreateFont (0, 0, 0, 0, 0, 0, 0, 0,
  104.                                    dwCharSet, 0, 0, 0, FIXED_PITCH, NULL)) ; 
  105.                
  106.           GetTextMetrics (hdc, &tm) ;
  107.           cxChar = tm.tmAveCharWidth ;
  108.           cyChar = tm.tmHeight ;
  109.  
  110.           DeleteObject (SelectObject (hdc, GetStockObject (SYSTEM_FONT))) ;
  111.           ReleaseDC (hwnd, hdc) ;
  112.  
  113.                // Allocate memory for display lines
  114.  
  115.           if (pmsg)
  116.                free (pmsg) ;
  117.  
  118.           cLinesMax = cyClientMax / cyChar ;
  119.           pmsg = malloc (cLinesMax * sizeof (MSG)) ;
  120.           cLines = 0 ;
  121.                                    // fall through
  122.      case WM_SIZE:
  123.           if (message == WM_SIZE)
  124.           {
  125.                cxClient = LOWORD (lParam) ;
  126.                cyClient = HIWORD (lParam) ;
  127.           }
  128.                // Calculate scrolling rectangle
  129.  
  130.           rectScroll.left   = 0 ;
  131.           rectScroll.right  = cxClient ;
  132.           rectScroll.top    = cyChar ;
  133.           rectScroll.bottom = cyChar * (cyClient / cyChar) ;
  134.  
  135.           InvalidateRect (hwnd, NULL, TRUE) ;
  136.  
  137.           if (message == WM_INPUTLANGCHANGE)
  138.                return TRUE ;
  139.  
  140.           return 0 ;
  141.           
  142.      case WM_KEYDOWN:
  143.      case WM_KEYUP:
  144.      case WM_CHAR:
  145.      case WM_DEADCHAR:
  146.      case WM_SYSKEYDOWN:
  147.      case WM_SYSKEYUP:
  148.      case WM_SYSCHAR:
  149.      case WM_SYSDEADCHAR: 
  150.  
  151.                // Rearrange storage array
  152.  
  153.           for (i = cLinesMax - 1 ; i > 0 ; i--)
  154.           {
  155.                pmsg[i] = pmsg[i - 1] ;
  156.           }
  157.                // Store new message
  158.  
  159.           pmsg[0].hwnd = hwnd ;
  160.           pmsg[0].message = message ;
  161.           pmsg[0].wParam = wParam ;
  162.           pmsg[0].lParam = lParam ;
  163.  
  164.           cLines = min (cLines + 1, cLinesMax) ;
  165.  
  166.                // Scroll up the display
  167.  
  168.           ScrollWindow (hwnd, 0, -cyChar, &rectScroll, &rectScroll) ;
  169.  
  170.           break ;        // ie, call DefWindowProc so Sys messages work
  171.           
  172.      case WM_PAINT:
  173.           hdc = BeginPaint (hwnd, &ps) ;
  174.  
  175.           SelectObject (hdc, CreateFont (0, 0, 0, 0, 0, 0, 0, 0,
  176.                                    dwCharSet, 0, 0, 0, FIXED_PITCH, NULL)) ; 
  177.           
  178.           SetBkMode (hdc, TRANSPARENT) ;
  179.           TextOut (hdc, 0, 0, szTop, lstrlen (szTop)) ;
  180.           TextOut (hdc, 0, 0, szUnd, lstrlen (szUnd)) ;
  181.  
  182.           for (i = 0 ; i < min (cLines, cyClient / cyChar - 1) ; i++)
  183.           {
  184.                iType = pmsg[i].message == WM_CHAR ||
  185.                        pmsg[i].message == WM_SYSCHAR ||
  186.                        pmsg[i].message == WM_DEADCHAR ||
  187.                        pmsg[i].message == WM_SYSDEADCHAR ;
  188.  
  189.                GetKeyNameText (pmsg[i].lParam, szKeyName, 
  190.                                sizeof (szKeyName) / sizeof (TCHAR)) ;
  191.  
  192.                TextOut (hdc, 0, (cyClient / cyChar - 1 - i) * cyChar, szBuffer,
  193.                         wsprintf (szBuffer, szFormat [iType],
  194.                              szMessage [pmsg[i].message - WM_KEYFIRST],                   
  195.                              pmsg[i].wParam,
  196.                              (PTSTR) (iType ? TEXT (" ") : szKeyName),
  197.                              (TCHAR) (iType ? pmsg[i].wParam : ' '),
  198.                              LOWORD (pmsg[i].lParam),
  199.                              HIWORD (pmsg[i].lParam) & 0xFF,
  200.                              0x01000000 & pmsg[i].lParam ? szYes  : szNo,
  201.                              0x20000000 & pmsg[i].lParam ? szYes  : szNo,
  202.                              0x40000000 & pmsg[i].lParam ? szDown : szUp,
  203.                              0x80000000 & pmsg[i].lParam ? szUp   : szDown)) ;
  204.           }
  205.           DeleteObject (SelectObject (hdc, GetStockObject (SYSTEM_FONT))) ;
  206.           EndPaint (hwnd, &ps) ;
  207.           return 0 ;
  208.  
  209.      case WM_DESTROY:
  210.           PostQuitMessage (0) ;
  211.           return 0 ;
  212.      }
  213.      return DefWindowProc (hwnd, message, wParam, lParam) ;
  214. }
  215.